<?php

namespace Apps\Common\Libs;

use Apps\Common\Enum\SearchDataType;
use Apps\Common\Models\Activity;
use Apps\Common\Models\BeautyParlorService;
use Apps\Common\Models\OpenSearchSource;
use Phalcon\Db\RawValue;
use PhalconPlus\Common\Component;

/**
 * 同步搜索所需的数据
 * @package Apps\Common\Libs
 */
class SearchASync extends Component
{
    private $gearmanServers = null;
    private $jobName = 'search_data_sync';

    public function __construct()
    {
        $this->gearmanServers = $this->di->get('appConfig')->gearman->toArray();
        if (!$this->gearmanServers) {
            throw new \Exception('gearman server empty.');
        }
    }

    /**
     * @param int $id
     * @param int $type
     */
    public function noticeSync($id, $type)
    {
        /*
        $client = new gmClient($this->gearmanServers);
        $self = $this;
        $client->errorLog = function($msg) use ($self) {
            $self->logError($msg);
        };
        $client->traceLog = function($msg) use ($self) {
            $self->logDebug($msg);
        };
        $client->async($this->jobName, ['id'=>$id, 'type'=>$type]);
        */
        switch($type) {
            case SearchDataType::Activity:
                $this->syncActivity($id);
                break;
            case SearchDataType::BeautyParlors:
                $this->syncBP($id);
                break;
            case SearchDataType::BeautyParlorService:
                $this->syncBPS($id);
                break;
            case SearchDataType::Question:
                $this->syncQuestion($id);
                break;
        }
    }

    private function syncActivity($id)
    {
        $info = Activity::findFirst('activity_id = ' . $id);
        if(!$info) {
            return false;
        }
        // 删除数据
        if($info->activity_state <= 0) {
            $this->delete(SearchDataType::Activity, $info->activity_id);
            return true;
        }
        // 同步数据
        $title = $info->activity_title;
        $searchContent = \Apps\Common\Libs\BeautyParlor::formatServiceIntro($info->activity_intro, $this->getDI());
        $tagInt = $info->city_id;
        $tagStr = strval($info->activity_type);
        $showData = json_encode([
            'id' => $info->activity_id,
            'type' => $info->activity_type,
            'title' => $info->activity_title,
            'cover' => $info->activity_cover,
            'state' => $info->activity_state,
        ]);
        $this->save(SearchDataType::Activity, $id, $showData, $title, $searchContent, $tagInt, $tagStr);
        return true;
    }

    private function syncBP($id)
    {
        $info = \Apps\Common\Models\BeautyParlor::findFirst('bp_id = ' . $id);
        if(!$info) {
            return false;
        }
        // 删除数据
        if($info->bp_state <= 0) {
            $this->delete(SearchDataType::BeautyParlors, $info->bp_id);
            return true;
        }
        // 同步数据
        $bpTags = \Apps\Common\Libs\BeautyParlor::getTags($id);
        // 标题中包含的内容
        $titleArr = [
            $info->bp_name,
            implode(',', $bpTags),
            $info->bp_address
        ];
        $title = implode(',', $titleArr);
        $searchContent = $info->bp_intro;
        $tagInt = \Apps\Common\Libs\SysArea::districtToOpenCityId($info->bp_district);
        $tagStr = strval($info->bp_tel);
        $showData = json_encode([
            'id' => $info->bp_id,
            'name' => $info->bp_name,
            'cover' => $info->bp_cover,
            'address' => $info->bp_address,
            'medal_refund' => \Apps\Common\Libs\BeautyParlor::getMedalRefund($info->bp_medal),
            'medal_verify' => \Apps\Common\Libs\BeautyParlor::getMedalRefund($info->bp_medal),
            'tags' => $bpTags
        ]);
        $this->save(SearchDataType::BeautyParlors, $id, $showData, $title, $searchContent, $tagInt, $tagStr);
        return true;
    }

    private function syncBPS($id)
    {
        $info = BeautyParlorService::findFirst('service_id = ' . $id);
        if(!$info) {
            return false;
        }
        // 删除数据
        if($info->service_state <= 0) {
            $this->delete(SearchDataType::BeautyParlorService, $info->service_id);
            return true;
        }
        // 店铺数据
        $bpInfo = \Apps\Common\Models\BeautyParlor::findFirst('bp_id = ' . $info->beauty_parlor_id);
        // 同步数据
        // 标题中包含的内容
        $titleArr = [
            $info->service_name,
            $info->service_description
        ];
        $title = implode(',', $titleArr);
        $searchContent = \Apps\Common\Libs\BeautyParlor::formatServiceIntro($info->service_intro, $this->getDI());
        $tagInt = $info->service_is_sell;
        $tagStr = '';
        $showData = json_encode([
            'id' => $info->service_id,
            'name' => $info->service_name,
            'cover' => $info->service_cover,
            'price' => $info->service_price,
            'unit' => $info->service_unit,
            'description' => $info->service_description,
            'bp_id' => $bpInfo->bp_id,
            'bp_name' => $bpInfo->bp_name
        ]);
        $this->save(SearchDataType::BeautyParlorService, $id, $showData, $title, $searchContent, $tagInt, $tagStr);
        return true;
    }

    private function syncQuestion($id)
    {
        $columns = ['u.user_id',
            'u.user_nickname',
            'u.user_cover',
            'question_id',
            'question_content',
            'question_pics',
            'answer_num',
            'question_browsers',
            'question_follows',
            'question_addtime',
            'question_state',
            'tag_title'
        ];
        $info = \Apps\Common\Models\Question::query()
            ->columns($columns)
            ->leftJoin('Apps\Common\Models\UserBase',
                'Apps\Common\Models\Question.user_id = u.user_id','u')
            ->leftJoin('Apps\Common\Models\QuestionTag',
                'Apps\Common\Models\Question.question_tag = qt.tag_id', 'qt')
            ->where('question_id = :id:', ['id' => $id])
            ->execute()->getFirst();

        if(!$info) {
            return false;
        }
        // 删除数据
        if($info->question_state <= 0) {
            $this->delete(SearchDataType::Question, $info->question_id);
            return true;
        }
        // 同步数据
        $title = $info->tag_title;
        $searchContent = $info->question_content;
        $tagInt = $info->answer_num;
        $tagStr = '';
        $showData = json_encode([
            'user_id' => $info->user_id,
            'user_nickname' => $info->user_nickname,
            'user_cover' => $info->user_cover,
            'question_id' => $info->question_id,
            'question_content' => $info->question_content,
            'question_pics' => $info->question_pics,
            'answer_num' => $info->answer_num,
            'browser_num' => $info->question_browsers,
            'follow_num' => $info->question_follows,
            'addtime' => $info->question_addtime
        ]);
        $this->save(SearchDataType::Question, $id, $showData, $title, $searchContent, $tagInt, $tagStr);
        return true;

    }

    /**
     * 保存
     * @param $type
     * @param $id
     * @param $showData
     * @param $title
     * @param $content
     * @param $tagInt
     * @param $tagStr
     */
    private function save($type, $id, $showData, $title, $content, $tagInt, $tagStr)
    {
        // 是否存在
        $info = $this->getSearchSource($type, $id);
        if (!!$info) {
            // 修改
            $info->update([
                'info_show_data' => $showData,
                'search_title' => $title,
                'search_content' => $content,
                'info_tag_int' => $tagInt,
                'info_tag_str' => $tagStr,
                'sync_time' => new RawValue('NOW()')
            ]);
        } else {
            // 添加
            $info = new OpenSearchSource();
            $info->info_type = $type;
            $info->info_id = $id;
            $info->info_show_data = $showData;
            $info->search_title = $title;
            $info->search_content = $content;
            $info->info_tag_int = $tagInt;
            $info->info_tag_str = $tagStr;
            if(!$info->save()) {
                $this->logDatabaseError($info);
            }
        }
    }

    /**
     * 删除
     * @param $type
     * @param $id
     */
    private function delete($type, $id)
    {
        $info = $this->getSearchSource($type, $id);
        if(!!$info) {
            $info->delete();
        }
    }

    /**
     * 获取数据源信息
     * @param $type
     * @param $id
     * @return \Apps\Common\Models\OpenSearchSource
     */
    private function getSearchSource($type, $id)
    {
        return OpenSearchSource::query()
            ->where('info_type = :type: AND info_id = :id:', ['type'=>$type, 'id'=>$id])
            ->execute()
            ->getFirst();
    }

    /*id` bigint(19) unsigned NOT NULL AUTO_INCREMENT,
  `info_type` int(11) NOT NULL COMMENT '数据类型，1-美容院,2-美容院服务项目,3-活动,4-问答',
  `info_id` bigint(20) NOT NULL COMMENT '内容的ID',
  `info_show_data` text NOT NULL COMMENT '用于显示的数据',
  `search_content` text NOT NULL COMMENT '搜索的内容',
  `sync_state` int(11) NOT NULL DEFAULT '0' COMMENT '同步状态，0-等待同步，1-已经同步',
  `sync_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '同步的时间',
    */
    private static $self = null;

    /**
     * SearchASync实例
     * @return SearchASync|null
     */
    public static function Instance()
    {
        if (self::$self == null) {
            self::$self = new self();
        }
        return self::$self;
    }
}